#[derive(Debug)]
pub struct Stack<T> {
    top: Option<Box<StackNode<T>>>,
}

#[derive(Debug, Clone)]
struct StackNode<T> {
    val: T,
    next: Option<Box<StackNode<T>>>,
}

impl<T> StackNode<T> {
    fn new(val: T) -> StackNode<T> {
        StackNode { val, next: None }
    }
}

impl<T> Stack<T> {
    pub fn new() -> Stack<T> {
        Stack { top: None }
    }

    pub fn push(&mut self, val: T) {
        let mut node = StackNode::new(val);
        let next = self.top.take();
        node.next = next;
        self.top = Some(box node);
    }
    pub fn pop(&mut self) -> Option<T> {
        let val = self.top.take();
        match val {
            None => None,
            Some(mut node) => {
                self.top = node.next.take();
                Some(node.val)
            }
        }
    }
}

#[test]
fn stack_work() {
    #[derive(PartialEq, Eq, Debug)]
    struct Test {
        value: i32,
    }
    let a = Test { value: 5 };
    let b = Test { value: 6 };
    let mut stack = Stack::<&Test>::new();
    assert_eq!(stack.pop(), None);

    stack.push(&a);
    stack.push(&b);

    println!("{:?}", stack);

    assert_eq!(stack.pop(), Some(&b));
    assert_eq!(stack.pop(), Some(&a));
    assert_eq!(stack.pop(), None);
}
